<!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>segment tree</title>
        <style>
</style>
        
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Microsoft/vscode/extensions/markdown-language-features/media/markdown.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Microsoft/vscode/extensions/markdown-language-features/media/highlight.css">
<style>
            body {
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', system-ui, 'Ubuntu', 'Droid Sans', sans-serif;
                font-size: 14px;
                line-height: 1.6;
            }
        </style>
        <style>
.task-list-item { list-style-type: none; } .task-list-item-checkbox { margin-left: -20px; vertical-align: middle; }
</style>
        
        
        
    </head>
    <body class="vscode-light">
        <h1 id="segment-tree">segment tree</h1>
<ul>
<li>单点更新，区域检索，用线段树</li>
<li>区域更新，单点检索，用前缀和差分</li>
</ul>
<h1 id="1-2019年写的版本-支持同时query-minmax-values-和update">1. 2019年写的版本， 支持同时query min/max values 和update</h1>
<p>D:\myproject\python\leetcode\tree\<a href="http://segmenttree1.py">segmenttree1.py</a></p>
<pre><code class="language-python"><div><span class="hljs-comment"># coding:utf-8</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># 线段树</span>
<span class="hljs-comment">#</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span><span class="hljs-params">(object)</span>:</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, left, right)</span>:</span>
        self.min_v = <span class="hljs-number">0</span>
        self.max_v = <span class="hljs-number">0</span>
        self.left = left
        self.right = right
        self.left_child = <span class="hljs-literal">None</span>
        self.right_child = <span class="hljs-literal">None</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">create_tree</span><span class="hljs-params">(nums, left, right)</span>:</span>
    node = Node(left, right)
    <span class="hljs-keyword">if</span> left == right:
        node.min_val = nums[left]
        node.max_val = nums[left]
    <span class="hljs-keyword">else</span>:
        mid = (left + right) // <span class="hljs-number">2</span>
        node.left_child = create_tree(nums, left, mid)
        node.right_child = create_tree(nums, mid+<span class="hljs-number">1</span>, right)
        node.min_val = min(node.left_child.min_val, node.right_child.min_val)
        node.max_val = max(node.left_child.max_val, node.right_child.max_val)
        
    <span class="hljs-keyword">return</span> node

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">query</span><span class="hljs-params">(node, left_q, right_q)</span>:</span>
    <span class="hljs-comment">#print(f"[query] {node.left}~{node.right} {left_q}~{right_q}")</span>
    <span class="hljs-keyword">if</span> node.left &gt;= right_q <span class="hljs-keyword">or</span> node.right &lt;= left_q:
        <span class="hljs-keyword">return</span> float(<span class="hljs-string">'inf'</span>), -float(<span class="hljs-string">'inf'</span>)
    <span class="hljs-keyword">if</span> node.left &gt;= left_q <span class="hljs-keyword">and</span> node.right &lt;= right_q:
        <span class="hljs-keyword">return</span> node.min_val, node.max_val

    min1, max1 = query(node.left_child, left_q, right_q)
    min2, max2 = query(node.right_child, left_q, right_q)
    <span class="hljs-keyword">return</span> min(min1, min2), max(max1, max2)

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">update_tree</span><span class="hljs-params">(node, pos, val)</span>:</span>  
    <span class="hljs-keyword">if</span> node.left &gt; pos <span class="hljs-keyword">or</span> node.right &lt; pos:
        <span class="hljs-keyword">return</span>
    <span class="hljs-keyword">if</span> pos == node.left <span class="hljs-keyword">and</span> pos == node.right:
        node.min_val = val
        node.max_val = val
    <span class="hljs-keyword">else</span>:
        mid = (node.left + node.right) // <span class="hljs-number">2</span>
        <span class="hljs-keyword">if</span> pos &lt;= mid:
            update_tree(node.left_child, pos, val)
        <span class="hljs-keyword">else</span>:
            update_tree(node.right_child, pos, val)
        node.min_val = min(node.left_child.min_val, node.right_child.min_val)
        node.max_val = max(node.left_child.max_val, node.right_child.max_val)

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test1</span><span class="hljs-params">()</span>:</span>
    nums = [<span class="hljs-number">1</span>,<span class="hljs-number">7</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">2</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>,<span class="hljs-number">9</span>]
    root = create_tree(nums, <span class="hljs-number">0</span>, len(nums)<span class="hljs-number">-1</span>)
    print(root)
    query_ranges = [(<span class="hljs-number">0</span>,<span class="hljs-number">1</span>), (<span class="hljs-number">2</span>,<span class="hljs-number">5</span>), (<span class="hljs-number">4</span>,<span class="hljs-number">9</span>), (<span class="hljs-number">10</span>,<span class="hljs-number">11</span>)]
    <span class="hljs-keyword">for</span> left,right <span class="hljs-keyword">in</span> query_ranges:
        min_v, max_v = query(root, left, right)
        print(<span class="hljs-string">f"<span class="hljs-subst">{left}</span>:<span class="hljs-subst">{right}</span> min_v=<span class="hljs-subst">{min_v}</span> max_v=<span class="hljs-subst">{max_v}</span>"</span>)

    update_tree(root, <span class="hljs-number">2</span>, <span class="hljs-number">11</span>)
    <span class="hljs-keyword">for</span> left,right <span class="hljs-keyword">in</span> query_ranges:
        min_v, max_v = query(root, left, right)
        print(<span class="hljs-string">f"<span class="hljs-subst">{left}</span>:<span class="hljs-subst">{right}</span> min_v=<span class="hljs-subst">{min_v}</span> max_v=<span class="hljs-subst">{max_v}</span>"</span>)    

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span><span class="hljs-params">()</span>:</span>
    test1()

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
    main()
    
</div></code></pre>
<h1 id="2-2020年看了tushar-roy又写了一个版本-支持min-query-其实和第一个版本一样">2. 2020年看了tushar roy，又写了一个版本， 支持min query, 其实和第一个版本一样</h1>
<ul>
<li><a href="https://www.youtube.com/watch?v=ZBHKZF5w4YU&amp;list=PLrmLmBdmIlpv_jNDXtJGYTPNQ2L1gdHxu&amp;index=22">https://www.youtube.com/watch?v=ZBHKZF5w4YU&amp;list=PLrmLmBdmIlpv_jNDXtJGYTPNQ2L1gdHxu&amp;index=22</a></li>
<li>D:\myproject\python\leetcode\tree\segmenttree_20200525.py</li>
</ul>
<pre><code class="language-python"><div><span class="hljs-comment"># coding:utf-8</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># segment tree </span>
<span class="hljs-comment"># the minimal value inside a range query</span>
<span class="hljs-comment">#</span>

<span class="hljs-keyword">import</span> click

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span><span class="hljs-params">(object)</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, left, right)</span>:</span>
        self.left = left
        self.right = right
        self.minimal = <span class="hljs-literal">None</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">create_tree</span><span class="hljs-params">(nums, left, right)</span>:</span>
    <span class="hljs-keyword">if</span> left == right:
        node = Node(left, right)
        node.minimal = nums[left]
        <span class="hljs-keyword">return</span> node
    mid = (left + right) // <span class="hljs-number">2</span>
    node = Node(left, right)
    node.left_child = create_tree(nums, left, mid)
    node.right_child = create_tree(nums, mid+<span class="hljs-number">1</span>, right)
    node.minimal = min(node.left_child.minimal, node.right_child.minimal)
    <span class="hljs-keyword">return</span> node

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">query</span><span class="hljs-params">(node, q_left, q_right)</span>:</span>
    <span class="hljs-keyword">if</span> q_left &lt;= node.left <span class="hljs-keyword">and</span> q_right &gt;= node.right:
        <span class="hljs-keyword">return</span> node.minimal
    <span class="hljs-keyword">if</span> q_left &gt;= node.right <span class="hljs-keyword">or</span> q_right &lt;= node.left:
        <span class="hljs-keyword">return</span> float(<span class="hljs-string">'inf'</span>)
    <span class="hljs-keyword">return</span> min(query(node.left_child, q_left, q_right), query(node.right_child, q_left, q_right))

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">update</span><span class="hljs-params">(node, pos, val)</span>:</span>
    <span class="hljs-keyword">if</span> node.left == pos <span class="hljs-keyword">and</span> node.right == pos:
        node.minimal = val
        <span class="hljs-keyword">return</span>
    <span class="hljs-keyword">if</span> pos &lt; node.left <span class="hljs-keyword">or</span> pos &gt; node.right:
        <span class="hljs-keyword">return</span>
    mid = (node.left + node.right) // <span class="hljs-number">2</span>
    <span class="hljs-keyword">if</span> pos &lt;= mid:
        update(node.left_child, pos, val)
        node.minimal = min(node.minimal, node.left_child.minimal)
    <span class="hljs-keyword">else</span>:
        update(node.right_child, pos, val)
        node.minimal = min(node.minimal, node.right_child.minimal)




<span class="hljs-meta">@click.group()</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span><span class="hljs-params">()</span>:</span>
    <span class="hljs-keyword">pass</span>

<span class="hljs-meta">@main.command()</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test1</span><span class="hljs-params">()</span>:</span>
    nums = [<span class="hljs-number">3</span>,<span class="hljs-number">9</span>,<span class="hljs-number">-1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">7</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">10</span>]
    ranges = [(<span class="hljs-number">0</span>,<span class="hljs-number">1</span>), (<span class="hljs-number">0</span>,<span class="hljs-number">3</span>), (<span class="hljs-number">1</span>,<span class="hljs-number">7</span>)]
    node = create_tree(nums, <span class="hljs-number">0</span>, len(nums)<span class="hljs-number">-1</span>)
    <span class="hljs-keyword">for</span> q_left, q_right <span class="hljs-keyword">in</span> ranges:
        minimal = query(node, q_left, q_right)
        print(<span class="hljs-string">f"<span class="hljs-subst">{q_left}</span> <span class="hljs-subst">{q_right}</span> = <span class="hljs-subst">{minimal}</span>"</span>)

    update(node, <span class="hljs-number">3</span>, <span class="hljs-number">-5</span>)
    <span class="hljs-keyword">for</span> q_left, q_right <span class="hljs-keyword">in</span> ranges:
        minimal = query(node, q_left, q_right)
        print(<span class="hljs-string">f"<span class="hljs-subst">{q_left}</span> <span class="hljs-subst">{q_right}</span> = <span class="hljs-subst">{minimal}</span>"</span>)




<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
    main()

</div></code></pre>
<h1 id="3-用segment来求range-sum">3. 用segment来求range sum</h1>
<p>D:\myproject\python\leetcode\tree\segmenttree_20200526.py</p>
<pre><code><code><div># coding:utf-8
#
# segment tree 
# the sum value inside a range query
#
# https://www.youtube.com/watch?v=xuoQdt5pHj0&amp;list=PLrmLmBdmIlpv_jNDXtJGYTPNQ2L1gdHxu&amp;index=23
#

import click

class Node(object):
    def __init__(self, left, right):
        self.left = left
        self.right = right
        self.sum = 0

def create_tree(nums, left, right):
    if left == right:
        node = Node(left, right)
        node.sum = nums[left]
        return node
    mid = (left + right) // 2
    node = Node(left, right)
    node.left_child = create_tree(nums, left, mid)
    node.right_child = create_tree(nums, mid+1, right)
    node.sum = node.left_child.sum + node.right_child.sum
    return node

def query(node, q_left, q_right):
    if q_left &lt;= node.left and q_right &gt;= node.right:
        return node.sum
    if q_left &gt;= node.right or q_right &lt;= node.left:
        return 0
    return query(node.left_child, q_left, q_right) + query(node.right_child, q_left, q_right)

def update(node, pos, val):
    if node.left == pos and node.right == pos:
        node.sum = val
        return
    if pos &lt; node.left or pos &gt; node.right:
        return
    mid = (node.left + node.right) // 2
    if pos &lt;= mid:
        update(node.left_child, pos, val)
    else:
        update(node.right_child, pos, val)
    node.sum = node.left_child.sum + node.right_child.sum




@click.group()
def main():
    pass

@main.command()
def test1():
    nums = [3,9,-1, 2, 7, 0, 1, 10]
    ranges = [(0,1), (0,3), (1,7)]
    node = create_tree(nums, 0, len(nums)-1)
    for q_left, q_right in ranges:
        sum = query(node, q_left, q_right)
        print(f&quot;{q_left} {q_right} = {sum}&quot;)

    update(node, 3, -5)
    for q_left, q_right in ranges:
        sum = query(node, q_left, q_right)
        print(f&quot;{q_left} {q_right} = {sum}&quot;)




if __name__ == '__main__':
    main()



</div></code></code></pre>
<h1 id="4-zkw线段树">4. zkw线段树</h1>
<p>普通线段树的增强版</p>
<h1 id="5-论那些小而美的算法技巧差分数组前缀和-labuladong">5. 论那些小而美的算法技巧：差分数组/前缀和， labuladong</h1>
<p>大家好，我是算法老司机 labuladong，本文给大家介绍一个小而美的算法技巧：差分数组。</p>
<p>读完本文，你可以去解决力扣第 1109 题「航班预订统计」，难度 Medium</p>
<p>差分数组技巧是前文 前缀和技巧详解 写过的前缀和技巧的兄弟。</p>
<p>前缀和主要适用的场景是原始数组不会被修改的情况下，频繁查询某个区间的累加和。</p>
<p>没看过前文没关系，这里简单介绍一下前缀和，核心代码就是下面这段：</p>
<pre><code class="language-java"><div><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PrefixSum</span> </span>{
    <span class="hljs-comment">// 前缀和数组</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span>[] prefix;

    <span class="hljs-comment">/* 输入一个数组，构造前缀和 */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">PrefixSum</span><span class="hljs-params">(<span class="hljs-keyword">int</span>[] nums)</span> </span>{
        prefix = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[nums.length + <span class="hljs-number">1</span>];
        <span class="hljs-comment">// 计算 nums 的累加和</span>
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">1</span>; i &lt; prefix.length; i++) {
            prefix[i] = prefix[i - <span class="hljs-number">1</span>] + nums[i - <span class="hljs-number">1</span>];
        }
    }

    <span class="hljs-comment">/* 查询闭区间 [i, j] 的累加和 */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">query</span><span class="hljs-params">(<span class="hljs-keyword">int</span> i, <span class="hljs-keyword">int</span> j)</span> </span>{
        <span class="hljs-keyword">return</span> prefix[j + <span class="hljs-number">1</span>] - prefix[i];
    }
}
</div></code></pre>
<p>prefix[i]就代表着nums[0..i-1]所有元素的累加和，如果我们想求区间nums[i..j]的累加和，只要计算prefix[j+1] - prefix[i]即可，而不需要遍历整个区间求和。</p>
<p>本文讲一个和前缀和思想非常类似的算法技巧「差分数组」，差分数组的主要适用场景是频繁对原始数组的某个区间的元素进行增减。</p>
<p>比如说，我给你输入一个数组nums，然后又要求给区间nums[2..6]全部加 1，再给nums[3..9]全部减 3，再给nums[0..4]全部加 2，再给…</p>
<p>一通操作猛如虎，然后问你，最后nums数组的值是什么？</p>
<p>常规的思路很容易，你让我给区间nums[i..j]加上val，那我就一个 for 循环给它们都加上呗，还能咋样？这种思路的时间复杂度是 O(N)，由于这个场景下对nums的修改非常频繁，所以效率会很低下。</p>
<p>这里就需要差分数组的技巧，类似前缀和技巧构造的prefix数组，我们先对nums数组构造一个diff差分数组，diff[i]就是nums[i]和nums[i-1]之差：</p>
<pre><code class="language-java"><div><span class="hljs-keyword">int</span>[] diff = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[nums.length];
<span class="hljs-comment">// 构造差分数组</span>
diff[<span class="hljs-number">0</span>] = nums[<span class="hljs-number">0</span>];
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">1</span>; i &lt; nums.length; i++) {
    diff[i] = nums[i] - nums[i - <span class="hljs-number">1</span>];
}
</div></code></pre>
<p>通过这个diff差分数组是可以反推出原始数组nums的，代码逻辑如下：</p>
<pre><code class="language-java"><div><span class="hljs-keyword">int</span>[] res = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[diff.length];
<span class="hljs-comment">// 根据差分数组构造结果数组</span>
res[<span class="hljs-number">0</span>] = diff[<span class="hljs-number">0</span>];
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">1</span>; i &lt; diff.length; i++) {
    res[i] = res[i - <span class="hljs-number">1</span>] + diff[i];
}
</div></code></pre>
<p>这样构造差分数组diff，就可以快速进行区间增减的操作，如果你想对区间nums[i..j]的元素全部加 3，那么只需要让diff[i] += 3，然后再让diff[j+1] -= 3即可：</p>
<p>原理很简单，回想diff数组反推nums数组的过程，diff[i] += 3意味着给nums[i..]所有的元素都加了 3，然后diff[j+1] -= 3又意味着对于nums[j+1..]所有元素再减 3，那综合起来，是不是就是对nums[i..j]中的所有元素都加 3 了？</p>
<p>只要花费 O(1) 的时间修改diff数组，就相当于给nums的整个区间做了修改。多次修改diff，然后通过diff数组反推，即可得到nums修改后的结果。</p>
<p>现在我们把差分数组抽象成一个类，包含increment方法和result方法：</p>
<pre><code class="language-java"><div><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Difference</span> </span>{
    <span class="hljs-comment">// 差分数组</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span>[] diff;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Difference</span><span class="hljs-params">(<span class="hljs-keyword">int</span>[] nums)</span> </span>{
        <span class="hljs-keyword">assert</span> nums.length &gt; <span class="hljs-number">0</span>;
        diff = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[nums.length];
        <span class="hljs-comment">// 构造差分数组</span>
        diff[<span class="hljs-number">0</span>] = nums[<span class="hljs-number">0</span>];
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">1</span>; i &lt; nums.length; i++) {
            diff[i] = nums[i] - nums[i - <span class="hljs-number">1</span>];
        }
    }

    <span class="hljs-comment">/* 给闭区间 [i,j] 增加 val（可以是负数）*/</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">increment</span><span class="hljs-params">(<span class="hljs-keyword">int</span> i, <span class="hljs-keyword">int</span> j, <span class="hljs-keyword">int</span> val)</span> </span>{
        diff[i] += val;
        <span class="hljs-keyword">if</span> (j + <span class="hljs-number">1</span> &lt; diff.length) {
            diff[j + <span class="hljs-number">1</span>] -= val;
        }
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span>[] result() {
        <span class="hljs-keyword">int</span>[] res = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[diff.length];
        <span class="hljs-comment">// 根据差分数组构造结果数组</span>
        res[<span class="hljs-number">0</span>] = diff[<span class="hljs-number">0</span>];
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">1</span>; i &lt; diff.length; i++) {
            res[i] = res[i - <span class="hljs-number">1</span>] + diff[i];
        }
        <span class="hljs-keyword">return</span> res;
    }
}
</div></code></pre>
<p>这里注意一下increment方法中的 if 语句：</p>
<pre><code><code><div>public void increment(int i, int j, int val) {
    diff[i] += val;
    if (j + 1 &lt; diff.length) {
        diff[j + 1] -= val;
    }
}
</div></code></code></pre>
<p>当j+1 &gt;= diff.length时，说明是对nums[i]及以后的整个数组都进行修改，那么就不需要再给diff数组减val了。</p>
<p>下面针对 LC  1109 题「航班预订统计」：</p>
<p>这么一看，不就是一道标准的差分数组题嘛？我们可以直接复用刚才写的类：</p>
<pre><code class="language-java"><div><span class="hljs-keyword">int</span>[] corpFlightBookings(<span class="hljs-keyword">int</span>[][] bookings, <span class="hljs-keyword">int</span> n) {
    <span class="hljs-comment">// nums 初始化为全 0</span>
    <span class="hljs-keyword">int</span>[] nums = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[n];
    <span class="hljs-comment">// 构造差分解法</span>
    Difference df = <span class="hljs-keyword">new</span> Difference(nums);

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span>[] booking : bookings) {
        <span class="hljs-comment">// 注意转成数组索引要减一哦</span>
        <span class="hljs-keyword">int</span> i = booking[<span class="hljs-number">0</span>] - <span class="hljs-number">1</span>;
        <span class="hljs-keyword">int</span> j = booking[<span class="hljs-number">1</span>] - <span class="hljs-number">1</span>;
        <span class="hljs-keyword">int</span> val = booking[<span class="hljs-number">2</span>];
        <span class="hljs-comment">// 对区间 nums[i..j] 增加 val</span>
        df.increment(i, j, val);
    }
    <span class="hljs-comment">// 返回最终的结果数组</span>
    <span class="hljs-keyword">return</span> df.result();
}
</div></code></pre>
<p>这道题就解决了。</p>

    </body>
    </html>